package core;

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

import card.Card;

/**
 * 
 * @author Oscar
 * A class for initiating the players who are participating in the game.
 */
public class PlayerGenerator {
	private static PlayerGenerator me;
	
	private List<Card> deck = new ArrayList<Card>();
	
	public static PlayerGenerator getInstance(){
		if(me == null){
			me = new PlayerGenerator();
		}
		return me;
	}
	
	/**
	 * A huge method that initiate the game in regards of players, cards and starting lands. 
	 * Creates a list of players, a list of ingame cards as well as a counter that depends
	 * on the amount of players. It then broadcast these variables to Core. After all this
	 * has been done it sets the starting land of each player.
	 * @param p
	 */
	public void initiatePlayers(int p){
		List<Player> players = new ArrayList<Player>();
		int playerIdCounter = 0;
		List<Card> ingameCards=new ArrayList<Card>();
		
		for(int i = 1; i<=p; i++){
			deck = DeckGenerator.getInstance().generateDeck();
			players.add(addPlayer(deck, playerIdCounter));
			playerIdCounter++;
			ingameCards.addAll(deck);
		}
		
		Core core = Core.getInstance();
		core.setPlayers(players);
		core.addIngameCards(ingameCards);
		
		setStartingPositions();
	}
	
	/**
	 * Adds a player with the used deck to the list of players.
	 * @param deck
	 * @param id
	 * @return
	 */
	public Player addPlayer(List<Card> deck, int id){
		Player p = new Player(id);
		p.setDeck(deck);
		return p;
	}
	
	/**
	 * returns the Point of a tile, as it is stored in the Player object
	 * tested for 2, 3, 4 and 6 players.
	 * @param amountOfPlayers ranging from 2 to 6
	 * @param idOfThisPlayer
	 * @return
	 */
	private static Point getStartPos(int amountOfPlayers, int idOfThisPlayer){
		int mapSize=Constants.MAPSIZE;
		int half=mapSize/2;
		Point center = new Point(half, half);
		Point[] validDirections = {new Point(-1,0), new Point(0,-1), new Point(1,-1), new Point(1,0), new Point(0,1), new Point(-1,1)};
		//must always range from 0 to 5;
		int chosenDirection=(idOfThisPlayer*6/amountOfPlayers)%6;
		Point returnPoint = new Point(center.x+validDirections[chosenDirection].x*half, center.y+validDirections[chosenDirection].y*half);
		return returnPoint;
		
	}
	
	/**
	 * Makes each player their owner of their starting land.
	 */
	private void setStartingPositions(){
		Core core = Core.getInstance();
		
		for(int i = 0; i<core.players.size();i++){
			MapUtil.getTile(getStartPos(core.players.size(), core.players.get(i).getPlayerId())).setOwningPlayer(core.players.get(i));
		}
	}
}